﻿using HslCommunication.Profinet.Melsec;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;

namespace OKDebug
{
    public partial class FrmSanLingPLC : Form
    {
        private MelsecMcNet _melsecMcNet;
        public FrmSanLingPLC()
        {
            InitializeComponent();
        }

        private void btnConnectSanLingPLC_Click(object sender, EventArgs e)
        {
            if (btnConnectSanLingPLC.Text.Equals("已连接"))
            {
                if (MessageBox.Show("是否断开连接？", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK)
                {
                    _melsecMcNet.ConnectClose();
                    btnConnectSanLingPLC.ForeColor = SystemColors.ControlText;
                    btnConnectSanLingPLC.BackColor = SystemColors.Control;
                    btnConnectSanLingPLC.Text = "连接";
                };

                return;
            }

            string ip = this.txtSanLingPLCIP.Text.Trim();
            string port = this.txtSanLingPLCPort.Text.Trim();

            if (string.IsNullOrEmpty(ip))
            {
                this.txtSanLingPLCIP.Focus();
                MessageBox.Show("IP为空！");
                return;
            }

            if (string.IsNullOrEmpty(port))
            {
                this.txtSanLingPLCPort.Focus();
                MessageBox.Show("端口为空！");
                return;
            }

            int _port = Convert.ToInt32(port);
            _melsecMcNet = new MelsecMcNet(ip, _port);
            _melsecMcNet.ConnectTimeOut = 3000;
            var result = _melsecMcNet.ConnectServer();
            if (result.IsSuccess)
            {
                btnConnectSanLingPLC.ForeColor = Color.White;
                btnConnectSanLingPLC.BackColor = Color.Green;
                btnConnectSanLingPLC.Text = "已连接";
                MessageBox.Show("连接成功！");
            }
            else
            {
                MessageBox.Show("连接失败！" + result.Message);
            }
        }

        private void btnSanLingCharRead_Click(object sender, EventArgs e)
        {
            if (!btnConnectSanLingPLC.Text.Equals("已连接"))
            {
                MessageBox.Show("未连接！");
                return;
            }

            string strAddress = this.txtSanLingCharAddr.Text.Trim();
            string length = this.txtSanLingLength.Text.Trim();
            if (string.IsNullOrEmpty(strAddress))
            {
                this.txtSanLingCharAddr.Focus();
                MessageBox.Show("地址为空!");
                return;
            }

            if (string.IsNullOrEmpty(length))
            {
                this.txtSanLingLength.Focus();
                MessageBox.Show("长度为空!");
                return;
            }

            ushort _length = Convert.ToUInt16(length);
            var re = _melsecMcNet.ReadString(strAddress, _length);
            if (re.IsSuccess && re.Content != null)
            {
                var index = re.Content.IndexOf('\0');
                var str = re.Content.Substring(0, index);
                this.txtSanLingCharContent.Text = str;
            }
            else
            {
                MessageBox.Show("读取失败！" + re.Message);
            }
        }

        private void btnSanLingCharWrite_Click(object sender, EventArgs e)
        {
            if (!btnConnectSanLingPLC.Text.Equals("已连接"))
            {
                MessageBox.Show("未连接！");
                return;
            }

            string strAddress = this.txtSanLingCharAddr.Text.Trim();
            string length = this.txtSanLingLength.Text.Trim();
            string str = this.txtSanLingCharContent.Text.Trim();
            if (string.IsNullOrEmpty(strAddress))
            {
                this.txtSanLingCharAddr.Focus();
                MessageBox.Show("地址为空!");
                return;
            }

            if (string.IsNullOrEmpty(length))
            {
                this.txtSanLingLength.Focus();
                MessageBox.Show("长度为空!");
                return;
            }

            ushort _length = Convert.ToUInt16(length);
            byte[] buffer = new byte[_length];
            Encoding.ASCII.GetBytes(str).CopyTo(buffer, 0);
            var result = _melsecMcNet.Write(strAddress, buffer);
            if (result.IsSuccess)
            {
                MessageBox.Show("写入成功！");
            }
            else
            {
                MessageBox.Show("写入失败！" + result.Message);
            }
        }

        private void btnSanLingFloatRead_Click(object sender, EventArgs e)
        {
            if (!btnConnectSanLingPLC.Text.Equals("已连接"))
            {
                MessageBox.Show("未连接！");
                return;
            }

            string strAddress = this.txtSanLingFloatAddr.Text.Trim();
            if (string.IsNullOrEmpty(strAddress))
            {
                this.txtSanLingFloatAddr.Focus();
                MessageBox.Show("地址为空!");
                return;
            }

            var re = _melsecMcNet.ReadFloat(strAddress);
            if (re.IsSuccess)
            {
                this.txtSanLingFloatContent.Text = re.Content.ToString();
            }
            else
            {
                MessageBox.Show("读取失败！" + re.Message);
            }
        }

        private void btnSanLingFloatWrite_Click(object sender, EventArgs e)
        {
            if (!btnConnectSanLingPLC.Text.Equals("已连接"))
            {
                MessageBox.Show("未连接！");
                return;
            }

            string strAddress = this.txtSanLingFloatAddr.Text.Trim();
            string str = this.txtSanLingFloatContent.Text.Trim();
            if (string.IsNullOrEmpty(strAddress))
            {
                this.txtSanLingFloatAddr.Focus();
                MessageBox.Show("地址为空!");
                return;
            }

            if (string.IsNullOrEmpty(str))
            {
                this.txtSanLingFloatContent.Focus();
                MessageBox.Show("内容为空!");
                return;
            }

            byte[] buffer = new byte[4];
            float val = Convert.ToSingle(str);
            BitConverter.GetBytes(val).CopyTo(buffer, 0);
            var result = _melsecMcNet.Write(strAddress, buffer);
            if (result.IsSuccess)
            {
                MessageBox.Show("写入成功！");
            }
            else
            {
                MessageBox.Show("写入失败！" + result.Message);
            }
        }

        private void btnSanLingShortRead_Click(object sender, EventArgs e)
        {
            if (!btnConnectSanLingPLC.Text.Equals("已连接"))
            {
                MessageBox.Show("未连接！");
                return;
            }

            string strAddress = this.txtSanLingShortAddr.Text.Trim();
            if (string.IsNullOrEmpty(strAddress))
            {
                this.txtSanLingShortAddr.Focus();
                MessageBox.Show("地址为空!");
                return;
            }

            var re = _melsecMcNet.ReadUInt16(strAddress);
            if (re.IsSuccess)
            {
                this.txtSanLingShortContent.Text = re.Content.ToString();
            }
            else
            {
                MessageBox.Show("读取失败！" + re.Message);
            }
        }

        private void btnSanLingShortWrite_Click(object sender, EventArgs e)
        {
            if (!btnConnectSanLingPLC.Text.Equals("已连接"))
            {
                MessageBox.Show("未连接！");
                return;
            }

            string strAddress = this.txtSanLingShortAddr.Text.Trim();
            string str = this.txtSanLingShortContent.Text.Trim();
            if (string.IsNullOrEmpty(strAddress))
            {
                this.txtSanLingShortAddr.Focus();
                MessageBox.Show("地址为空!");
                return;
            }

            if (string.IsNullOrEmpty(str))
            {
                this.txtSanLingShortContent.Focus();
                MessageBox.Show("内容为空!");
                return;
            }

            byte[] buffer = new byte[2];
            ushort val = Convert.ToUInt16(str);
            BitConverter.GetBytes(val).CopyTo(buffer, 0);
            var result = _melsecMcNet.Write(strAddress, buffer);
            if (result.IsSuccess)
            {
                MessageBox.Show("写入成功！");
            }
            else
            {
                MessageBox.Show("写入失败！" + result.Message);
            }
        }

        private void btnSanLingIntRead_Click(object sender, EventArgs e)
        {
            if (!btnConnectSanLingPLC.Text.Equals("已连接"))
            {
                MessageBox.Show("未连接！");
                return;
            }

            string strAddress = this.txtSanLingIntAddr.Text.Trim();
            if (string.IsNullOrEmpty(strAddress))
            {
                this.txtSanLingIntAddr.Focus();
                MessageBox.Show("地址为空!");
                return;
            }

            var re = _melsecMcNet.ReadInt32(strAddress);
            if (re.IsSuccess)
            {
                this.txtSanLingIntContent.Text = re.Content.ToString();
            }
            else
            {
                MessageBox.Show("读取失败！" + re.Message);
            }
        }

        private void btnSanLingIntWrite_Click(object sender, EventArgs e)
        {
            if (!btnConnectSanLingPLC.Text.Equals("已连接"))
            {
                MessageBox.Show("未连接！");
                return;
            }

            string strAddress = this.txtSanLingIntAddr.Text.Trim();
            string str = this.txtSanLingIntContent.Text.Trim();
            if (string.IsNullOrEmpty(strAddress))
            {
                this.txtSanLingIntAddr.Focus();
                MessageBox.Show("地址为空!");
                return;
            }

            if (string.IsNullOrEmpty(str))
            {
                this.txtSanLingIntContent.Focus();
                MessageBox.Show("内容为空!");
                return;
            }

            byte[] buffer = new byte[4];
            int val = Convert.ToInt32(str);
            BitConverter.GetBytes(val).CopyTo(buffer, 0);
            var result = _melsecMcNet.Write(strAddress, buffer);
            if (result.IsSuccess)
            {
                MessageBox.Show("写入成功！");
            }
            else
            {
                MessageBox.Show("写入失败！" + result.Message);
            }
        }

        private void btnSanLingBitRead_Click(object sender, EventArgs e)
        {
            if (!btnConnectSanLingPLC.Text.Equals("已连接"))
            {
                MessageBox.Show("未连接！");
                return;
            }

            string strAddress = this.txtSanLingBitAddr.Text.Trim();
            string index = this.txtSanLingBitIndex.Text.Trim();
            if (string.IsNullOrEmpty(strAddress))
            {
                this.txtSanLingBitAddr.Focus();
                MessageBox.Show("地址为空!");
                return;
            }

            if (string.IsNullOrEmpty(index))
            {
                this.txtSanLingBitIndex.Focus();
                MessageBox.Show("位索引为空!");
                return;
            }

            ushort _index = Convert.ToUInt16(index);
            var re = _melsecMcNet.Read(strAddress, 1);
            if (re.IsSuccess)
            {
                int res_index = 0;
                if (_index > 7)
                {
                    res_index = 1;
                    _index -= 8;
                }

                int val = (re.Content[res_index] >> _index) & 0x01;
                this.txtSanLingBitContent.Text = val.ToString();
            }
            else
            {
                MessageBox.Show("读取失败！" + re.Message);
            }
        }

        private void btnSanLingBitWrite_Click(object sender, EventArgs e)
        {
            if (!btnConnectSanLingPLC.Text.Equals("已连接"))
            {
                MessageBox.Show("未连接！");
                return;
            }

            if (MessageBox.Show("谨慎操作！确认写入吗？", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) != DialogResult.OK)
            {
                return;
            };

            string strAddress = this.txtSanLingBitAddr.Text.Trim();
            string str = this.txtSanLingBitContent.Text.Trim();
            string index = this.txtSanLingBitIndex.Text.Trim();
            if (string.IsNullOrEmpty(strAddress))
            {
                this.txtSanLingBitAddr.Focus();
                MessageBox.Show("地址为空!");
                return;
            }

            if (string.IsNullOrEmpty(index))
            {
                this.txtSanLingBitIndex.Focus();
                MessageBox.Show("位索引为空!");
                return;
            }

            if (string.IsNullOrEmpty(str))
            {
                this.txtSanLingBitContent.Focus();
                MessageBox.Show("内容为空!");
                return;
            }

            byte oldVal;
            int res_index = 0;
            ushort _index = Convert.ToUInt16(index);
            var re = _melsecMcNet.Read(strAddress, 1);
            if (re.IsSuccess)
            {
                if (_index > 7)
                {
                    res_index = 1;
                    _index -= 8;
                }

                oldVal = re.Content[res_index];
            }
            else
            {
                MessageBox.Show("读取原值失败！" + re.Message);
                return;
            }

            byte[] buffer = re.Content;
            oldVal = Common.SetbitValue(oldVal, _index + 1, "1".Equals(str) ? true : false);
            buffer[res_index] = oldVal;
            var result = _melsecMcNet.Write(strAddress, buffer);
            if (result.IsSuccess)
            {
                this.txtSanLingBitContent.Text = string.Empty;
                MessageBox.Show("写入成功！");
            }
            else
            {
                MessageBox.Show("写入失败！" + result.Message);
            }
        }

        private void btnSanLingUniRead_Click(object sender, EventArgs e)
        {
            if (!btnConnectSanLingPLC.Text.Equals("已连接"))
            {
                MessageBox.Show("未连接！");
                return;
            }

            string strAddress = this.txtSanLingUniAddr.Text.Trim();
            if (string.IsNullOrEmpty(strAddress))
            {
                this.txtSanLingUniAddr.Focus();
                MessageBox.Show("地址为空!");
                return;
            }

            string length = this.txtSanLingUniLength.Text.Trim();
            if (string.IsNullOrEmpty(length))
            {
                this.txtSanLingUniLength.Focus();
                MessageBox.Show("长度为空!");
                return;
            }

            int _length = Convert.ToInt32(length);
            string addr = strAddress.ToUpper().Replace("D", string.Empty);
            int _addr = Convert.ToInt32(addr);

            string content = string.Empty;
            for (var i = 0; i < _length; i++)
            {
                var re = _melsecMcNet.ReadInt16("D" + (_addr + i));
                if (re.IsSuccess)
                {
                    short val = re.Content;
                    if (i < 2)
                    {
                        content += val;
                    }
                    else
                    {
                        if (val >= 0x4e00)
                        {
                            string unicodeStr = "\\u" + Convert.ToString(val, 16);
                            string chineseStr = UnicodeToString(unicodeStr);
                            content += chineseStr;
                        }
                        else
                        {
                            char chr = Convert.ToChar(val);
                            content += chr;
                        }
                    }

                    this.txtSanLingUniContent.Text = content;
                }
                else
                {
                    MessageBox.Show("读取失败！" + re.Message);
                    return;
                }
            }
        }

        private void btnSanLingUniWrite_Click(object sender, EventArgs e)
        {
            if (!btnConnectSanLingPLC.Text.Equals("已连接"))
            {
                MessageBox.Show("未连接！");
                return;
            }

            string strAddress = this.txtSanLingUniAddr.Text.Trim();
            string str = this.txtSanLingUniContent.Text.Trim();
            if (string.IsNullOrEmpty(strAddress))
            {
                this.txtSanLingUniAddr.Focus();
                MessageBox.Show("地址为空!");
                return;
            }

            if (string.IsNullOrEmpty(str))
            {
                this.txtSanLingUniContent.Focus();
                MessageBox.Show("内容为空!");
                return;
            }

            byte[] buffer = new byte[4 + str.Length * 2];
            short head = 31;
            short length = (short)str.Length;
            BitConverter.GetBytes(head).CopyTo(buffer, 0);
            BitConverter.GetBytes(length).CopyTo(buffer, 2);
            for (var i = 0; i < str.Length; i++)
            {
                char chr = str[i];
                short val = 0;
                if (chr >= 0x4e00 && chr <= 0x9fbb)
                {
                    string _uniCode = Convert.ToString(chr, 16);
                    val = Convert.ToInt16("0x" + _uniCode, 16);
                }
                else
                {
                    int asciiValue = chr;
                    val = (short)asciiValue;
                }

                BitConverter.GetBytes(val).CopyTo(buffer, 4 + i * 2);
            }

            var result = _melsecMcNet.Write(strAddress, buffer);
            if (result.IsSuccess)
            {
                MessageBox.Show("写入成功！");
            }
            else
            {
                MessageBox.Show("写入失败！" + result.Message);
            }
        }

        /// <summary>
        /// Unicode码转汉字
        /// </summary>
        /// <param name="unicode">Unicode码</param>
        /// <returns>汉字</returns>
        public string UnicodeToString(string unicode)
        {
            string result = "";
            //正则匹配
            Regex reg = new Regex(@"(?i)\\u([0-9a-f]{4})");
            result = reg.Replace(unicode, delegate (Match m)
            {
                return ((char)Convert.ToInt32(m.Groups[1].Value, 16)).ToString();
            });
            return result;
        }
    }
}
